/*                                                         
** Copyright (C) 2008, 2009 Ricard Marxer <email@ricardmarxer.com>
**                                                                  
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 3 of the License, or   
** (at your option) any later version.                                 
**                                                                     
** This program is distributed in the hope that it will be useful,     
** but WITHOUT ANY WARRANTY; without even the implied warranty of      
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the       
** GNU General Public License for more details.                        
**                                                                     
** You should have received a copy of the GNU General Public License   
** along with this program; if not, write to the Free Software         
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*/                                                                          

#include "Typedefs.h"
#include "Debug.h"

#include "LPCResidual.h"
#include "Utils.h"

using namespace std;
using namespace Eigen;

LPCResidual::LPCResidual(int frameSize) : 
  _frameSize( frameSize ),
  _filter( 1 )
{
  LOUDIA_DEBUG("LPCRESIDUAL: Constructor frameSize: " << frameSize);
  
  setup();
}

LPCResidual::~LPCResidual() {}


void LPCResidual::setup(){
  // Prepare the buffers
  LOUDIA_DEBUG("LPCRESIDUAL: Setting up...");

  reset();
  
  LOUDIA_DEBUG("LPCRESIDUAL: Finished set up...");
}


void LPCResidual::process(const MatrixXR& frame, const MatrixXR& lpcCoeffs, MatrixXR* residual){
  LOUDIA_DEBUG("LPCRESIDUAL: Processing...");
  const int rows = frame.rows();
  const int cols = frame.cols();

  if ( cols != _frameSize ) {
    // Throw ValueError, the frames passed are the wrong size
  }

  (*residual).resize(rows, cols);

  LOUDIA_DEBUG("LPCRESIDUAL: Processing setting filter");
  _filter.setA( lpcCoeffs.transpose() );
  
  for ( int row = 0; row < rows; row++ ) {
    
    LOUDIA_DEBUG("LPCRESIDUAL: Processing filter");
    _filter.process(frame.row( row ).transpose(), &_result);
    
    (*residual).row( row ) = _result.transpose();
  }

  LOUDIA_DEBUG("LPCRESIDUAL: Finished Processing");
}

void LPCResidual::reset(){
  // Initial values
}
